package limiter;

import com.google.common.util.concurrent.RateLimiter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.ratelimit.AbstractRateLimiter;
import org.springframework.cloud.gateway.support.ConfigurationService;
import org.springframework.context.annotation.Primary;
import org.springframework.validation.annotation.Validated;
import reactor.core.publisher.Mono;

import javax.validation.constraints.DecimalMin;
import java.util.HashMap;
import java.util.Objects;

/**
 * 整合guava限流  可参考 Redis限流实现 RedisRateLimiter
 * 限流入口类参考 ： RequestRateLimiterGatewayFilterFactory
 * @author wangzhilong
 * @date 2021/3/22
 */
public class DefaultRateLimiter extends AbstractRateLimiter<DefaultRateLimiter.Config> {

    private final Logger log = LoggerFactory.getLogger(getClass());

    /**
     * 每秒一个请求，每秒发一个令牌
     */
    private final RateLimiter limiter = RateLimiter.create(1);


    public DefaultRateLimiter(ConfigurationService configurationService) {
        super(Config.class, "default-rate-limit", configurationService);
    }

    @Override
    public Mono<Response> isAllowed(String routeId, String id) {
        log.info("DefaultRateLimiter 执行：routeId：{},id:{}", routeId, id);
        Config config = getConfig().get(routeId);
        limiter.setRate(Objects.isNull(config.getPermitsPerSecond()) ? 1 : config.getPermitsPerSecond());
        boolean isAllowed = limiter.tryAcquire();
        return Mono.just(new Response(isAllowed, new HashMap<>()));
    }

    @Validated
    public static class Config {

        @DecimalMin("0.1")
        private Double permitsPerSecond ;

        public Double getPermitsPerSecond() {
            return permitsPerSecond;
        }

        public void setPermitsPerSecond(Double permitsPerSecond) {
            this.permitsPerSecond = permitsPerSecond;
        }
    }
}
